home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / phpMyAdmin / pdf_schema.php < prev    next >
PHP Script  |  2005-03-05  |  53KB  |  1,545 lines

  1. <?php
  2. /* $Id: pdf_schema.php,v 2.13 2005/03/05 23:19:59 lem9 Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /**
  6.  * Contributed by Maxime Delorme and merged by lem9
  7.  */
  8.  
  9.  
  10. /**
  11.  * Gets some core scripts
  12.  */
  13. require_once('./libraries/grab_globals.lib.php');
  14. require_once('./libraries/common.lib.php');
  15.  
  16.  
  17. /**
  18.  * Settings for relation stuff
  19.  */
  20. require_once('./libraries/relation.lib.php');
  21. require_once('./libraries/transformations.lib.php');
  22.  
  23. $cfgRelation = PMA_getRelationsParam();
  24.  
  25.  
  26. /**
  27.  * Now in ./libraries/relation.lib.php we check for all tables
  28.  * that we need, but if we don't find them we are quiet about it
  29.  * so people can work without.
  30.  * This page is absolutely useless if you didn't set up your tables
  31.  * correctly, so it is a good place to see which tables we can and
  32.  * complain ;-)
  33.  */
  34. if (!$cfgRelation['pdfwork']) {
  35.     echo '<font color="red">' . $strError . '</font><br />' . "\n";
  36.     $url_to_goto = '<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $url_query . '">';
  37.     echo sprintf($strRelationNotWorking, $url_to_goto, '</a>') . "\n";
  38. }
  39.  
  40.  
  41. /**
  42.  * Gets the "fpdf" libraries and defines the pdf font path, use unicode version for unicode.
  43.  */
  44. define('FPDF_FONTPATH','./libraries/fpdf/font/');
  45. if ($charset == 'utf-8') {
  46.     define('PMA_PDF_FONT', 'FreeSans');
  47.     require_once('./libraries/fpdf/ufpdf.php');
  48.     class PMA_FPDF extends UFPDF {
  49.     };
  50. } else {
  51.     define('PMA_PDF_FONT', 'Arial');
  52.     require_once('./libraries/fpdf/fpdf.php');
  53.     class PMA_FPDF extends FPDF {
  54.     };
  55. }
  56.  
  57.  
  58. /**
  59.  * Extends the "FPDF" class and prepares the work
  60.  *
  61.  * @access  public
  62.  *
  63.  * @see     FPDF
  64.  */
  65. class PMA_PDF extends PMA_FPDF
  66. {
  67.     /**
  68.      * Defines private properties
  69.      */
  70.     var $x_min;
  71.     var $y_min;
  72.     var $l_marg = 10;
  73.     var $t_marg = 10;
  74.     var $scale;
  75.     var $title;
  76.     var $PMA_links;
  77.     var $Outlines=array();
  78.     var $def_outlines;
  79.     var $Alias ;
  80.     var $widths;
  81.  
  82.     /**
  83.      * The PMA_PDF constructor
  84.      *
  85.      * This function just refers to the "FPDF" constructor: with PHP3 a class
  86.      * must have a constructor
  87.      *
  88.      * @param  string  The page orientation (p, portrait, l or landscape)
  89.      * @param  string  The unit for sizes (pt, mm, cm or in)
  90.      * @param  mixed   The page format (A3, A4, A5, letter, legal or an array
  91.      *                 with page sizes)
  92.      *
  93.      * @access public
  94.      *
  95.      * @see     FPDF::FPDF()
  96.      */
  97.     function PMA_PDF($orientation = 'L', $unit = 'mm', $format = 'A4')
  98.     {
  99.         $this->Alias = array() ;
  100.         $this->FPDF($orientation, $unit, $format);
  101.     } // end of the "PMA_PDF()" method
  102.     function SetAlias($name, $value)
  103.     {
  104.         $this->Alias[$name] = $value ;
  105.     }
  106.     function _putpages()
  107.     {
  108.         if (count($this->Alias) > 0)
  109.         {
  110.             $nb=$this->page;
  111.             foreach ($this->Alias AS $alias => $value) {
  112.                 for ($n=1;$n<=$nb;$n++)
  113.                 $this->pages[$n]=$this->_strreplace($alias,$value,$this->pages[$n]);
  114.             }
  115.         }
  116.         parent::_putpages();
  117.     }
  118.  
  119.     /**
  120.      * Sets the scaling factor, defines minimum coordinates and margins
  121.      *
  122.      * @param  double  The scaling factor
  123.      * @param  double  The minimum X coordinate
  124.      * @param  double  The minimum Y coordinate
  125.      * @param  double  The left margin
  126.      * @param  double  The top margin
  127.      *
  128.      * @access public
  129.      */
  130.     function PMA_PDF_setScale($scale = 1, $x_min = 0, $y_min = 0, $l_marg = -1, $t_marg = -1)
  131.     {
  132.         $this->scale      = $scale;
  133.         $this->x_min      = $x_min;
  134.         $this->y_min      = $y_min;
  135.         if ($this->l_marg != -1) {
  136.             $this->l_marg = $l_marg;
  137.         }
  138.         if ($this->t_marg != -1) {
  139.             $this->t_marg = $t_marg;
  140.         }
  141.     } // end of the "PMA_PDF_setScale" function
  142.  
  143.  
  144.     /**
  145.      * Outputs a scaled cell
  146.      *
  147.      * @param   double   The cell width
  148.      * @param   double   The cell height
  149.      * @param   string   The text to output
  150.      * @param   mixed    Wether to add borders or not
  151.      * @param   integer  Where to put the cursor once the output is done
  152.      * @param   string   Align mode
  153.      * @param   integer  Whether to fill the cell with a color or not
  154.      *
  155.      * @access public
  156.      *
  157.      * @see     FPDF::Cell()
  158.      */
  159.     function PMA_PDF_cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0,$link ='')
  160.     {
  161.         $h = $h / $this->scale;
  162.         $w = $w / $this->scale;
  163.         $this->Cell($w, $h, $txt, $border, $ln, $align, $fill,$link);
  164.     } // end of the "PMA_PDF_cellScale" function
  165.  
  166.  
  167.     /**
  168.      * Draws a scaled line
  169.      *
  170.      * @param   double  The horizontal position of the starting point
  171.      * @param   double  The vertical position of the starting point
  172.      * @param   double  The horizontal position of the ending point
  173.      * @param   double  The vertical position of the ending point
  174.      *
  175.      * @access public
  176.      *
  177.      * @see     FPDF::Line()
  178.      */
  179.     function PMA_PDF_lineScale($x1, $y1, $x2, $y2)
  180.     {
  181.         $x1 = ($x1 - $this->x_min) / $this->scale + $this->l_marg;
  182.         $y1 = ($y1 - $this->y_min) / $this->scale + $this->t_marg;
  183.         $x2 = ($x2 - $this->x_min) / $this->scale + $this->l_marg;
  184.         $y2 = ($y2 - $this->y_min) / $this->scale + $this->t_marg;
  185.         $this->Line($x1, $y1, $x2, $y2);
  186.     } // end of the "PMA_PDF_lineScale" function
  187.  
  188.  
  189.     /**
  190.      * Sets x and y scaled positions
  191.      *
  192.      * @param   double  The x position
  193.      * @param   double  The y position
  194.      *
  195.      * @access public
  196.      *
  197.      * @see     FPDF::SetXY()
  198.      */
  199.     function PMA_PDF_setXyScale($x, $y)
  200.     {
  201.         $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
  202.         $y = ($y - $this->y_min) / $this->scale + $this->t_marg;
  203.         $this->SetXY($x, $y);
  204.     } // end of the "PMA_PDF_setXyScale" function
  205.  
  206.  
  207.     /**
  208.      * Sets the X scaled positions
  209.      *
  210.      * @param   double  The x position
  211.      *
  212.      * @access public
  213.      *
  214.      * @see     FPDF::SetX()
  215.      */
  216.     function PMA_PDF_setXScale($x)
  217.     {
  218.         $x = ($x - $this->x_min) / $this->scale + $this->l_marg;
  219.         $this->SetX($x);
  220.     } // end of the "PMA_PDF_setXScale" function
  221.  
  222.  
  223.     /**
  224.      * Sets the scaled font size
  225.      *
  226.      * @param   double   The font size (in points)
  227.      *
  228.      * @access public
  229.      *
  230.      * @see     FPDF::SetFontSize()
  231.      */
  232.     function PMA_PDF_setFontSizeScale($size)
  233.     {
  234.         // Set font size in points
  235.         $size = $size / $this->scale;
  236.         $this->SetFontSize($size);
  237.     } // end of the "PMA_PDF_setFontSizeScale" function
  238.  
  239.  
  240.     /**
  241.      * Sets the scaled line width
  242.      *
  243.      * @param   double  The line width
  244.      *
  245.      * @access public
  246.      *
  247.      * @see     FPDF::SetLineWidth()
  248.      */
  249.     function PMA_PDF_setLineWidthScale($width)
  250.     {
  251.         $width = $width / $this->scale;
  252.         $this->SetLineWidth($width);
  253.     } // end of the "PMA_PDF_setLineWidthScale" function
  254.  
  255.  
  256.     /**
  257.      * Displays an error message
  258.      *
  259.      * @param   string   the error mesage
  260.      *
  261.      * @global  array    the PMA configuration array
  262.      * @global  integer  the current server id
  263.      * @global  string   the current language
  264.      * @global  string   the charset to convert to
  265.      * @global  string   the current database name
  266.      * @global  string   the current charset
  267.      * @global  string   the current text direction
  268.      * @global  string   a localized string
  269.      * @global  string   an other localized string
  270.      *
  271.      * @access  public
  272.      */
  273.     function PMA_PDF_die($error_message = '')
  274.     {
  275.         global $cfg;
  276.         global $server, $lang, $convcharset, $db;
  277.         global $charset, $text_dir, $strRunning, $strDatabase;
  278.  
  279.         require_once('./header.inc.php');
  280.  
  281.         echo '<p><b>PDF - '. $GLOBALS['strError'] . '</b></p>' . "\n";
  282.         if (!empty($error_message)) {
  283.             $error_message = htmlspecialchars($error_message);
  284.         }
  285.         echo '<p>' . "\n";
  286.         echo '    ' . $error_message . "\n";
  287.         echo '</p>' . "\n";
  288.  
  289.         echo '<a href="db_details_structure.php?' . PMA_generate_common_url($db)
  290.              . '">' . $GLOBALS['strBack'] . '</a>';
  291.         echo "\n";
  292.  
  293.         require_once('./footer.inc.php');
  294.     } // end of the "PMA_PDF_die()" function 
  295.  
  296.  
  297.     /**
  298.      * Aliases the "Error()" function from the FPDF class to the
  299.      * "PMA_PDF_die()" one
  300.      *
  301.      * @param   string   the error mesage
  302.      *
  303.      * @access  public
  304.      *
  305.      * @see     PMA_PDF_die()
  306.      */
  307.     function Error($error_message = '')
  308.     {
  309.         $this->PMA_PDF_die($error_message);
  310.     } // end of the "Error()" method
  311.  
  312.     function Header(){
  313.         //$datefmt
  314.         // We only show this if we find something in the new pdf_pages table
  315.         //
  316.         // This function must be named "Header" to work with the FPDF library
  317.  
  318.     global $cfgRelation,$db,$pdf_page_number,$with_doc;
  319.     if ($with_doc){
  320.         $test_query = 'SELECT * FROM ' . PMA_backquote($cfgRelation['pdf_pages'])
  321.                     . ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  322.                     . ' AND page_nr = \'' . $pdf_page_number . '\'';
  323.         $test_rs    = PMA_query_as_cu($test_query);
  324.         $pages = @PMA_DBI_fetch_assoc($test_rs);
  325.         $this->SetFont('', 'B', 14);
  326.         $this->Cell(0,6, ucfirst($pages['page_descr']),'B',1,'C');
  327.         $this->SetFont('', '');
  328.         $this->Ln();
  329.     }
  330.     }
  331.     function Footer(){
  332.         // This function must be named "Footer" to work with the FPDF library
  333.         global $with_doc;
  334.         if ($with_doc){
  335.             $this->SetY(-15);
  336.             $this->SetFont('', '',14);
  337.             $this->Cell(0,6, $GLOBALS['strPageNumber'] .' '.$this->PageNo() .'/{nb}','T',0,'C');
  338.             $this->Cell(0,6, PMA_localisedDate(),0,1,'R');
  339.             $this->SetY(20);
  340.         }
  341.     }
  342.     function Bookmark($txt,$level=0,$y=0)
  343. {
  344.    //Add a bookmark
  345.    $this->Outlines[0][]=$level;
  346.    $this->Outlines[1][]=$txt;
  347.    $this->Outlines[2][]=$this->page;
  348.    if ($y==-1)
  349.       $y=$this->GetY();
  350.    $this->Outlines[3][]=round($this->hPt-$y*$this->k,2);
  351. }
  352.  
  353. function _putbookmarks()
  354. {
  355.    if (count($this->Outlines)>0)
  356.    {
  357.       //Save object number
  358.       $memo_n = $this->n;
  359.       //Take the number of sub elements for an outline
  360.       $nb_outlines=sizeof($this->Outlines[0]);
  361.       $first_level=array();
  362.       $parent=array();
  363.       $parent[0]=1;
  364.       for ($i=0; $i<$nb_outlines; $i++)
  365.       {
  366.          $level=$this->Outlines[0][$i];
  367.          $kids=0;
  368.          $last=-1;
  369.          $prev=-1;
  370.          $next=-1;
  371.          if ($i>0 )
  372.          {
  373.             $cursor=$i-1;
  374.             //Take the previous outline in the same level
  375.             while ($this->Outlines[0][$cursor] > $level && $cursor > 0)
  376.                $cursor--;
  377.             if ($this->Outlines[0][$cursor] == $level)
  378.                $prev=$cursor;
  379.          }
  380.          if ($i<$nb_outlines-1)
  381.          {
  382.             $cursor=$i+1;
  383.             while (isset($this->Outlines[0][$cursor]) && $this->Outlines[0][$cursor] > $level)
  384.             {
  385.                //Take the immediate kid in level + 1
  386.                if ($this->Outlines[0][$cursor] == $level+1)
  387.                {
  388.                   $kids++;
  389.                   $last=$cursor;
  390.                }
  391.                $cursor++;
  392.             }
  393.             $cursor=$i+1;
  394.             //Take the next outline in the same level
  395.             while ($this->Outlines[0][$cursor] > $level && ($cursor+1 < sizeof($this->Outlines[0])))
  396.                $cursor++;
  397.             if ($this->Outlines[0][$cursor] == $level)
  398.                $next=$cursor;
  399.          }
  400.          $this->_newobj();
  401.          $parent[$level+1]=$this->n;
  402.          if ($level == 0)
  403.             $first_level[]=$this->n;
  404.          $this->_out('<<');
  405.          $this->_out('/Title ('.$this->Outlines[1][$i].')');
  406.          $this->_out('/Parent '.$parent[$level].' 0 R');
  407.          if ($prev != -1)
  408.             $this->_out('/Prev '.($memo_n+$prev+1).' 0 R');
  409.          if ($next != -1)
  410.             $this->_out('/Next '.($this->n+$next-$i).' 0 R');
  411.          $this->_out('/Dest ['.(1+(2*$this->Outlines[2][$i])).' 0 R /XYZ null '.$this->Outlines[3][$i].' null]');
  412.          if ($kids > 0)
  413.          {
  414.             $this->_out('/First '.($this->n+1).' 0 R');
  415.             $this->_out('/Last '.($this->n+$last-$i).' 0 R');
  416.             $this->_out('/Count -'.$kids);
  417.          }
  418.          $this->_out('>>');
  419.          $this->_out('endobj');
  420.       }
  421.       //First page of outlines
  422.       $this->_newobj();
  423.       $this->def_outlines = $this->n;
  424.       $this->_out('<<');
  425.       $this->_out('/Type');
  426.       $this->_out('/Outlines');
  427.       $this->_out('/First '.$first_level[0].' 0 R');
  428.       $this->_out('/Last '.$first_level[sizeof($first_level)-1].' 0 R');
  429.       $this->_out('/Count '.sizeof($first_level));
  430.       $this->_out('>>');
  431.       $this->_out('endobj');
  432.    }
  433. }
  434.  
  435. function _putresources()
  436. {
  437.    parent::_putresources();
  438.    $this->_putbookmarks();
  439. }
  440.  
  441. function _putcatalog()
  442. {
  443.    parent::_putcatalog();
  444.    if (count($this->Outlines)>0)
  445.    {
  446.       $this->_out('/Outlines '.$this->def_outlines.' 0 R');
  447.       $this->_out('/PageMode /UseOutlines');
  448.    }
  449. }
  450. function SetWidths($w)
  451. {
  452.    // column widths
  453.    $this->widths=$w;
  454. }
  455.  
  456. function Row($data,$links)
  457. {
  458.    // line height
  459.    $nb=0;
  460.    $data_cnt = count($data);
  461.    for ($i=0;$i<$data_cnt;$i++)
  462.       $nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));
  463.    $il = $this->FontSize;
  464.    $h=($il+1)*$nb;
  465.    // page break if necessary
  466.    $this->CheckPageBreak($h);
  467.    // draw the cells
  468.    $data_cnt = count($data);
  469.    for ($i=0;$i<$data_cnt;$i++)
  470.    {
  471.       $w=$this->widths[$i];
  472.       // save current position
  473.       $x=$this->GetX();
  474.       $y=$this->GetY();
  475.       // draw the border
  476.       $this->Rect($x,$y,$w,$h);
  477.       if (isset($links[$i]))
  478.       $this->Link($x,$y,$w,$h,$links[$i]);
  479.       // print text
  480.       $this->MultiCell($w,$il+1,$data[$i],0,'L');
  481.       // go to right side
  482.       $this->SetXY($x+$w,$y);
  483.    }
  484.    // go to line
  485.    $this->Ln($h);
  486. }
  487.  
  488. function CheckPageBreak($h)
  489. {
  490.    // if height h overflows, manual page break
  491.    if ($this->GetY()+$h>$this->PageBreakTrigger)
  492.       $this->AddPage($this->CurOrientation);
  493. }
  494.  
  495. function NbLines($w,$txt)
  496. {
  497.    // compute number of lines used by a multicell of width w
  498.    $cw=&$this->CurrentFont['cw'];
  499.    if ($w==0)
  500.       $w=$this->w-$this->rMargin-$this->x;
  501.    $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  502.    $s=str_replace("\r",'',$txt);
  503.    $nb=strlen($s);
  504.    if ($nb>0 and $s[$nb-1]=="\n")
  505.       $nb--;
  506.    $sep=-1;
  507.    $i=0;
  508.    $j=0;
  509.    $l=0;
  510.    $nl=1;
  511.    while ($i<$nb)
  512.    {
  513.       $c=$s[$i];
  514.       if ($c=="\n")
  515.       {
  516.          $i++;
  517.          $sep=-1;
  518.          $j=$i;
  519.          $l=0;
  520.          $nl++;
  521.          continue;
  522.       }
  523.       if ($c==' ')
  524.          $sep=$i;
  525.       $l+=isset($cw[ord($c)])?$cw[ord($c)]:0 ;
  526.       if ($l>$wmax)
  527.       {
  528.          if ($sep==-1)
  529.          {
  530.             if ($i==$j)
  531.                $i++;
  532.          }
  533.          else
  534.             $i=$sep+1;
  535.          $sep=-1;
  536.          $j=$i;
  537.          $l=0;
  538.          $nl++;
  539.       }
  540.       else
  541.          $i++;
  542.    }
  543.    return $nl;
  544. }
  545.  
  546. } // end of the "PMA_PDF" class
  547.  
  548.  
  549. /**
  550.  * Draws tables schema
  551.  *
  552.  * @access  private
  553.  *
  554.  * @see     PMA_RT
  555.  */
  556. class PMA_RT_Table
  557. {
  558.     /**
  559.      * Defines private properties
  560.      */
  561.     var $nb_fiels;
  562.     var $table_name;
  563.     var $width = 0;
  564.     var $height;
  565.     var $fields      = array();
  566.     var $height_cell = 6;
  567.     var $x, $y;
  568.     var $primary     = array();
  569.  
  570.  
  571.     /**
  572.      * Sets the width of the table
  573.      *
  574.      * @param   integer   The font size
  575.      *
  576.      * @global  object    The current PDF document
  577.      *
  578.      * @access  private
  579.      *
  580.      * @see     PMA_PDF
  581.      */
  582.     function PMA_RT_Table_setWidth($ff)
  583.     {
  584.         //  this looks buggy to me... does it really work if
  585.         //  there are fields that require wider cells than the name of the table?
  586.         global $pdf;
  587.  
  588.         foreach ($this->fields AS $field) {
  589.             $this->width = max($this->width, $pdf->GetStringWidth($field));
  590.         }
  591.         $this->width += $pdf->GetStringWidth('  ');
  592.         $pdf->SetFont($ff, 'B');
  593.         $this->width = max($this->width, $pdf->GetStringWidth('  ' . $this->table_name));
  594.         $pdf->SetFont($ff, '');
  595.     } // end of the "PMA_RT_Table_setWidth()" method
  596.  
  597.  
  598.     /**
  599.      * Sets the height of the table
  600.      *
  601.      * @access  private
  602.      */
  603.     function PMA_RT_Table_setHeight()
  604.     {
  605.         $this->height = (count($this->fields) + 1) * $this->height_cell;
  606.     } // end of the "PMA_RT_Table_setHeight()" method
  607.  
  608.  
  609.     /**
  610.      * Do draw the table
  611.      *
  612.      * @param   boolean   Whether to display table position or not
  613.      * @param   integer   The font size
  614.      * @param   boolean   Whether to display color
  615.      * @param   integer   The max. with among tables
  616.      *
  617.      * @global  object    The current PDF document
  618.      *
  619.      * @access  private
  620.      *
  621.      * @see     PMA_PDF
  622.      */
  623.     function PMA_RT_Table_draw($show_info, $ff, $setcolor=0)
  624.     {
  625.         global $pdf, $with_doc;
  626.  
  627.         $pdf->PMA_PDF_setXyScale($this->x, $this->y);
  628.         $pdf->SetFont($ff, 'B');
  629.         if ($setcolor) {
  630.             $pdf->SetTextColor(200);
  631.             $pdf->SetFillColor(0, 0, 128);
  632.         }
  633.         if ($with_doc) $pdf->SetLink($pdf->PMA_links['RT'][$this->table_name]['-'],-1);
  634.         else $pdf->PMA_links['doc'][$this->table_name]['-'] = '';
  635.         if ($show_info){
  636.             $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, sprintf('%.0f', $this->width) . 'x' . sprintf('%.0f', $this->height) . ' ' . $this->table_name, 1, 1, 'C', $setcolor, $pdf->PMA_links['doc'][$this->table_name]['-']);
  637.         } else {
  638.             $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, $this->table_name, 1, 1, 'C', $setcolor, $pdf->PMA_links['doc'][$this->table_name]['-']);
  639.         }
  640.         $pdf->PMA_PDF_setXScale($this->x);
  641.         $pdf->SetFont($ff, '');
  642.         $pdf->SetTextColor(0);
  643.         $pdf->SetFillColor(255);
  644.  
  645.         foreach ($this->fields AS $field) {
  646.             // loic1 : PHP3 fix
  647.             // if (in_array($field, $this->primary)) {
  648.             if ($setcolor) {
  649.                 if (PMA_isInto($field, $this->primary) != -1) {
  650.                     $pdf->SetFillColor(215, 121, 123);
  651.                 }
  652.                 if ($field == $this->displayfield) {
  653.                     $pdf->SetFillColor(142, 159, 224);
  654.                 }
  655.             }
  656.             if ($with_doc) $pdf->SetLink($pdf->PMA_links['RT'][$this->table_name][$field],-1);
  657.             else $pdf->PMA_links['doc'][$this->table_name][$field] = '';
  658.  
  659.  
  660.             $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, ' ' . $field, 1, 1, 'L', $setcolor,$pdf->PMA_links['doc'][$this->table_name][$field]);
  661.             $pdf->PMA_PDF_setXScale($this->x);
  662.             $pdf->SetFillColor(255);
  663.         } // end while
  664.  
  665.         /*if ($pdf->PageNo() > 1) {
  666.             $pdf->PMA_PDF_die($GLOBALS['strScaleFactorSmall']);
  667.         } */
  668.     } // end of the "PMA_RT_Table_draw()" method
  669.  
  670.  
  671.     /**
  672.      * The "PMA_RT_Table" constructor
  673.      *
  674.      * @param   string    The table name
  675.      * @param   integer   The font size
  676.      * @param   integer   The max. with among tables
  677.      *
  678.      * @global  object    The current PDF document
  679.      * @global  integer   The current page number (from the
  680.      *                    $cfg['Servers'][$i]['table_coords'] table)
  681.      * @global  array     The relations settings
  682.      * @global  string    The current db name
  683.      *
  684.      * @access  private
  685.      *
  686.      * @see     PMA_PDF, PMA_RT_Table::PMA_RT_Table_setWidth,
  687.      *          PMA_RT_Table::PMA_RT_Table_setHeight
  688.      */
  689.     function PMA_RT_Table($table_name, $ff, &$same_wide_width)
  690.     {
  691.         global $pdf, $pdf_page_number, $cfgRelation, $db;
  692.  
  693.         $this->table_name = $table_name;
  694.         $sql              = 'DESCRIBE ' .  PMA_backquote($table_name);
  695.         $result           = PMA_DBI_try_query($sql, NULL, PMA_DBI_QUERY_STORE);
  696.         if (!$result || !PMA_DBI_num_rows($result)) {
  697.             $pdf->PMA_PDF_die(sprintf($GLOBALS['strPdfInvalidTblName'], $table_name));
  698.         }
  699.         // load fields
  700.         while ($row = PMA_DBI_fetch_row($result)) {
  701.             $this->fields[] = $row[0];
  702.         }
  703.  
  704.         //height and width
  705.         $this->PMA_RT_Table_setWidth($ff);
  706.         $this->PMA_RT_Table_setHeight();
  707.         if ($same_wide_width < $this->width) {
  708.             $same_wide_width = $this->width;
  709.         }
  710.  
  711.         //x and y
  712.         $sql    = 'SELECT x, y FROM '
  713.                 . PMA_backquote($cfgRelation['table_coords'])
  714.                 .   ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  715.                 .   ' AND   table_name = \'' . PMA_sqlAddslashes($table_name) . '\''
  716.                 .   ' AND   pdf_page_number = ' . $pdf_page_number;
  717.         $result = PMA_query_as_cu($sql, FALSE, PMA_DBI_QUERY_STORE);
  718.  
  719.         if (!$result || !PMA_DBI_num_rows($result)) {
  720.             $pdf->PMA_PDF_die(sprintf($GLOBALS['strConfigureTableCoord'], $table_name));
  721.         }
  722.         list($this->x, $this->y) = PMA_DBI_fetch_row($result);
  723.         $this->x = (double) $this->x;
  724.         $this->y = (double) $this->y;
  725.         // displayfield
  726.         $this->displayfield = PMA_getDisplayField($db, $table_name);
  727.  
  728.         // index
  729.         $result = PMA_DBI_query('SHOW INDEX FROM ' . PMA_backquote($table_name) . ';', NULL, PMA_DBI_QUERY_STORE);
  730.         if (PMA_DBI_num_rows($result) > 0) {
  731.             while ($row = PMA_DBI_fetch_assoc($result)) {
  732.                 if ($row['Key_name'] == 'PRIMARY') {
  733.                     $this->primary[] = $row['Column_name'];
  734.                 }
  735.             }
  736.         } // end if
  737.     } // end of the "PMA_RT_Table()" method
  738. } // end class "PMA_RT_Table"
  739.  
  740.  
  741.  
  742. /**
  743.  * Draws relation links
  744.  *
  745.  * @access  private
  746.  *
  747.  * @see     PMA_RT
  748.  */
  749. class PMA_RT_Relation
  750. {
  751.     /**
  752.      * Defines private properties
  753.      */
  754.     var $x_src, $y_src;
  755.     var $src_dir ;
  756.     var $dest_dir;
  757.     var $x_dest, $y_dest;
  758.     var $w_tick = 5;
  759.  
  760.  
  761.     /**
  762.      * Gets arrows coordinates
  763.      *
  764.      * @param   string    The current table name
  765.      * @param   string    The relation column name
  766.      *
  767.      * @return  array     Arrows coordinates
  768.      *
  769.      * @access  private
  770.      */
  771.     function PMA_RT_Relation_getXy($table, $column)
  772.     {
  773.         $pos = array_search($column, $table->fields);
  774.         // x_left, x_right, y
  775.         return array($table->x, $table->x + + $table->width, $table->y + ($pos + 1.5) * $table->height_cell);
  776.     } // end of the "PMA_RT_Relation_getXy()" method
  777.  
  778.  
  779.     /**
  780.      * Do draws relation links
  781.      *
  782.      * @param   boolean   Whether to use one color per relation or not
  783.      * @param   integer   The id of the link to draw
  784.      *
  785.      * @global  object    The current PDF document
  786.      *
  787.      * @access  private
  788.      *
  789.      * @see     PMA_PDF
  790.      */
  791.     function PMA_RT_Relation_draw($change_color, $i)
  792.     {
  793.         global $pdf;
  794.  
  795.         if ($change_color){
  796.             $d    = $i % 6;
  797.             $j    = ($i - $d) / 6;
  798.             $j    = $j % 4;
  799.             $j++;
  800.             $case = array(
  801.                         array(1, 0, 0),
  802.                         array(0, 1, 0),
  803.                         array(0, 0, 1),
  804.                         array(1, 1, 0),
  805.                         array(1, 0, 1),
  806.                         array(0, 1, 1)
  807.                     );
  808.             list ($a, $b, $c) = $case[$d];
  809.             $e    = (1 - ($j - 1) / 6);
  810.             $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e);       }
  811.         else {
  812.             $pdf->SetDrawColor(0);
  813.         } // end if... else...
  814.  
  815.         $pdf->PMA_PDF_setLineWidthScale(0.2);
  816.         $pdf->PMA_PDF_lineScale($this->x_src, $this->y_src, $this->x_src + $this->src_dir * $this->w_tick, $this->y_src);
  817.         $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest, $this->x_dest, $this->y_dest);
  818.         $pdf->PMA_PDF_setLineWidthScale(0.1);
  819.         $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick, $this->y_src, $this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest);
  820.  
  821.         //arrow
  822.         $root2 = 2 * sqrt(2);
  823.         $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src + $this->w_tick / $root2);
  824.         $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src - $this->w_tick / $root2);
  825.  
  826.         $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest + $this->w_tick / $root2);
  827.         $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest - $this->w_tick / $root2);
  828.         $pdf->SetDrawColor(0);
  829.     } // end of the "PMA_RT_Relation_draw()" method
  830.  
  831.  
  832.     /**
  833.      * The "PMA_RT_Relation" constructor
  834.      *
  835.      * @param   string   The master table name
  836.      * @param   string   The relation field in the master table
  837.      * @param   string   The foreign table name
  838.      * @param   string   The relation field in the foreign table
  839.      *
  840.      *
  841.      * @access  private
  842.      *
  843.      * @see     PMA_RT_Relation::PMA_RT_Relation_getXy
  844.      */
  845.     function PMA_RT_Relation($master_table, $master_field,  $foreign_table, $foreign_field)
  846.     {
  847.         $src_pos    = $this->PMA_RT_Relation_getXy($master_table , $master_field);
  848.         $dest_pos   = $this->PMA_RT_Relation_getXy($foreign_table, $foreign_field);
  849.         $src_left   = $src_pos[0] - $this->w_tick;
  850.         $src_right  = $src_pos[1] + $this->w_tick;
  851.         $dest_left  = $dest_pos[0] - $this->w_tick;
  852.         $dest_right = $dest_pos[1] + $this->w_tick;
  853.  
  854.         $d1 = abs($src_left  - $dest_left);
  855.         $d2 = abs($src_right - $dest_left);
  856.         $d3 = abs($src_left  - $dest_right);
  857.         $d4 = abs($src_right - $dest_right);
  858.         $d  = min($d1, $d2, $d3, $d4);
  859.  
  860.         if ($d == $d1) {
  861.             $this->x_src    = $src_pos[0];
  862.             $this->src_dir  = -1;
  863.             $this->x_dest   = $dest_pos[0];
  864.             $this->dest_dir = -1;
  865.         } else if ($d == $d2) {
  866.             $this->x_src    = $src_pos[1];
  867.             $this->src_dir  = 1;
  868.             $this->x_dest   = $dest_pos[0];
  869.             $this->dest_dir = -1;
  870.         } else if ($d == $d3) {
  871.             $this->x_src    = $src_pos[0];
  872.             $this->src_dir  = -1;
  873.             $this->x_dest   = $dest_pos[1];
  874.             $this->dest_dir = 1;
  875.         } else {
  876.             $this->x_src    =  $src_pos[1];
  877.             $this->src_dir  = 1;
  878.             $this->x_dest   = $dest_pos[1];
  879.             $this->dest_dir = 1;
  880.         }
  881.         $this->y_src        = $src_pos[2];
  882.         $this->y_dest       = $dest_pos[2];
  883.     } // end of the "PMA_RT_Relation()" method
  884. } // end of the "PMA_RT_Relation" class
  885.  
  886.  
  887.  
  888. /**
  889.  * Draws and send the database schema
  890.  *
  891.  * @access  public
  892.  *
  893.  * @see     PMA_PDF
  894.  */
  895. class PMA_RT
  896. {
  897.     /**
  898.      * Defines private properties
  899.      */
  900.     var $tables    = array();
  901.     var $relations = array();
  902.     var $ff        = PMA_PDF_FONT;
  903.     var $x_max     = 0;
  904.     var $y_max     = 0;
  905.     var $scale;
  906.     var $x_min     = 100000;
  907.     var $y_min     = 100000;
  908.     var $t_marg    = 10;
  909.     var $b_marg    = 10;
  910.     var $l_marg    = 10;
  911.     var $r_marg    = 10;
  912.     var $tablewidth;
  913.     var $same_wide = 0;
  914.  
  915.     /**
  916.      * Sets X and Y minimum and maximum for a table cell
  917.      *
  918.      * @param   string   The table name
  919.      *
  920.      * @access  private
  921.      */
  922.     function PMA_RT_setMinMax($table)
  923.     {
  924.         $this->x_max = max($this->x_max, $table->x + $table->width);
  925.         $this->y_max = max($this->y_max, $table->y + $table->height);
  926.         $this->x_min = min($this->x_min, $table->x);
  927.         $this->y_min = min($this->y_min, $table->y);
  928.     } // end of the "PMA_RT_setMinMax()" method
  929.  
  930.  
  931.     /**
  932.      * Defines relation objects
  933.      *
  934.      * @param   string   The master table name
  935.      * @param   string   The relation field in the master table
  936.      * @param   string   The foreign table name
  937.      * @param   string   The relation field in the foreign table
  938.      *
  939.      * @access  private
  940.      *
  941.      * @see     PMA_RT_setMinMax()
  942.      */
  943.     function PMA_RT_addRelation($master_table , $master_field,  $foreign_table, $foreign_field)
  944.     {
  945.         if (!isset($this->tables[$master_table])) {
  946.             $this->tables[$master_table] = new PMA_RT_Table($master_table, $this->ff, $this->tablewidth);
  947.             $this->PMA_RT_setMinMax($this->tables[$master_table]);
  948.         }
  949.         if (!isset($this->tables[$foreign_table])) {
  950.             $this->tables[$foreign_table] = new PMA_RT_Table($foreign_table, $this->ff, $this->tablewidth);
  951.             $this->PMA_RT_setMinMax($this->tables[$foreign_table]);
  952.         }
  953.         $this->relations[] = new PMA_RT_Relation($this->tables[$master_table], $master_field, $this->tables[$foreign_table], $foreign_field);
  954.     } // end of the "PMA_RT_addRelation()" method
  955.  
  956.  
  957.     /**
  958.      * Draws the grid
  959.      *
  960.      * @global  object  the current PMA_PDF instance
  961.      *
  962.      * @access  private
  963.      *
  964.      * @see     PMA_PDF
  965.      */
  966.     function PMA_RT_strokeGrid()
  967.     {
  968.         global $pdf;
  969.  
  970.         $pdf->SetMargins(0, 0);
  971.         $pdf->SetDrawColor(200, 200, 200);
  972.  
  973.         // Draws horizontal lines
  974.         for ($l = 0; $l < 21; $l++) {
  975.             $pdf->line(0, $l * 10, $pdf->fh, $l * 10);
  976.             // Avoid duplicates
  977.             if ($l > 0) {
  978.                 $pdf->SetXY(0, $l * 10);
  979.                 $label = (string) sprintf('%.0f', ($l * 10 - $this->t_marg) * $this->scale + $this->y_min);
  980.                 $pdf->Cell(5, 5, ' ' . $label);
  981.             } // end if
  982.         } // end for
  983.  
  984.         // Draws vertical lines
  985.         for ($j = 0; $j < 30 ;$j++) {
  986.             $pdf->line($j * 10, 0, $j * 10, $pdf->fw);
  987.             $pdf->SetXY($j * 10, 0);
  988.             $label = (string) sprintf('%.0f', ($j * 10 - $this->l_marg) * $this->scale + $this->x_min);
  989.             $pdf->Cell(5, 7, $label);
  990.         } // end for
  991.     } // end of the "PMA_RT_strokeGrid()" method
  992.  
  993.  
  994.     /**
  995.      * Draws relation arrows
  996.      *
  997.      * @param   boolean  Whether to use one color per relation or not
  998.      *
  999.      * @access  private
  1000.      *
  1001.      * @see     PMA_RT_Relation::PMA_RT_Relation_draw()
  1002.      */
  1003.     function PMA_RT_drawRelations($change_color)
  1004.     {
  1005.         $i = 0;
  1006.         foreach ($this->relations AS $relation) {
  1007.             $relation->PMA_RT_Relation_draw($change_color, $i);
  1008.             $i++;
  1009.         } // end while
  1010.     } // end of the "PMA_RT_drawRelations()" method
  1011.  
  1012.  
  1013.     /**
  1014.      * Draws tables
  1015.      *
  1016.      * @param   boolean  Whether to display table position or not
  1017.      *
  1018.      * @access  private
  1019.      *
  1020.      * @see     PMA_RT_Table::PMA_RT_Table_draw()
  1021.      */
  1022.     function PMA_RT_drawTables($show_info,$draw_color=0)
  1023.     {
  1024.         foreach ($this->tables AS $table) {
  1025.             $table->PMA_RT_Table_draw($show_info, $this->ff,$draw_color);
  1026.         }
  1027.     } // end of the "PMA_RT_drawTables()" method
  1028.  
  1029.  
  1030.     /**
  1031.      * Ouputs the PDF document to a file
  1032.      *
  1033.      * @global  object   The current PDF document
  1034.      * @global  string   The current database name
  1035.      * @global  integer  The current page number (from the
  1036.      *                   $cfg['Servers'][$i]['table_coords'] table)
  1037.      *
  1038.      * @access  private
  1039.      *
  1040.      * @see     PMA_PDF
  1041.      */
  1042.     function PMA_RT_showRt()
  1043.     {
  1044.         global $pdf, $db, $pdf_page_number, $cfgRelation;
  1045.  
  1046.         $pdf->SetFontSize(14);
  1047.         $pdf->SetLineWidth(0.2);
  1048.         $pdf->SetDisplayMode('fullpage');
  1049.         //  Get the name of this pdfpage to use as filename (Mike Beck)
  1050.         $_name_sql  = 'SELECT page_descr FROM ' . PMA_backquote($cfgRelation['pdf_pages'])
  1051.                   .   ' WHERE page_nr = ' . $pdf_page_number;
  1052.         $_name_rs   = PMA_query_as_cu($_name_sql);
  1053.         if ($_name_rs) {
  1054.             $_name_row = PMA_DBI_fetch_row($_name_rs);
  1055.             $filename = $_name_row[0] . '.pdf';
  1056.         }
  1057.         // i don't know if there is a chance for this to happen, but rather be on the safe side:
  1058.         if (empty($filename)) {
  1059.             $filename = $pdf_page_number . '.pdf';
  1060.         }
  1061.         //$pdf->Output($db . '_' . $filename, TRUE);
  1062.         $pdf->Output($db . '_' . $filename, 'I'); // destination: Inline
  1063.     } // end of the "PMA_RT_showRt()" method
  1064.  
  1065.  
  1066.     /**
  1067.      * The "PMA_RT" constructor
  1068.      *
  1069.      * @param   mixed    The scaling factor
  1070.      * @param   integer  The page number to draw (from the
  1071.      *                   $cfg['Servers'][$i]['table_coords'] table)
  1072.      * @param   boolean  Whether to display table position or not
  1073.      * @param   boolean  Was originally whether to use one color per
  1074.      *                   relation or not, now enables/disables color
  1075.      *                   everywhere, due to some problems printing with color
  1076.      * @param   boolean  Whether to draw grids or not
  1077.      * @param   boolean  Whether all tables should have the same width or not
  1078.      *
  1079.      * @global  object   The current PDF document
  1080.      * @global  string   The current db name
  1081.      * @global  array    The relations settings
  1082.      *
  1083.      * @access  private
  1084.      *
  1085.      * @see     PMA_PDF
  1086.      */
  1087.     function PMA_RT( $which_rel, $show_info = 0, $change_color = 0 , $show_grid = 0, $all_tab_same_wide = 0, $orientation = 'L', $paper = 'A4')
  1088.     {
  1089.         global $pdf, $db, $cfgRelation, $with_doc;
  1090.  
  1091.         // Font face depends on the current language
  1092.         $this->ff        = str_replace('"', '', substr($GLOBALS['right_font_family'], 0, strpos($GLOBALS['right_font_family'], ',')));
  1093.  
  1094.         $this->same_wide = $all_tab_same_wide;
  1095.  
  1096.         // Initializes a new document
  1097.         $pdf          = new PMA_PDF('L', 'mm', $paper);
  1098.         $pdf->title   = sprintf($GLOBALS['strPdfDbSchema'], $GLOBALS['db'], $which_rel);
  1099.         $pdf->cMargin = 0;
  1100.         $pdf->Open();
  1101.         $pdf->SetTitle($pdf->title);
  1102.         $pdf->SetAuthor('phpMyAdmin ' . PMA_VERSION);
  1103.         $pdf->AliasNbPages();
  1104.  
  1105.         if ($GLOBALS['charset'] == 'utf-8') {
  1106.             // Force FreeSans for utf-8
  1107.             $this->ff = 'FreeSans';
  1108.             $pdf->AddFont('FreeSans','','FreeSans.php');
  1109.             $pdf->AddFont('FreeSans','B','FreeSansBold.php');
  1110.             $pdf->SetFont('FreeSans', '', 14);
  1111.         } else { 
  1112.             // fonts added to phpMyAdmin and considered non-standard by fpdf
  1113.             // (Note: those tahoma fonts are iso-8859-2 based)
  1114.             if ($this->ff == 'tahoma') {
  1115.                 $pdf->AddFont('tahoma','','tahoma.php');
  1116.                 $pdf->AddFont('tahoma','B','tahomab.php');
  1117.             }
  1118.         }
  1119.         $pdf->SetFont($this->ff, '', 14);
  1120.         $pdf->SetAutoPageBreak('auto');
  1121.  
  1122.         // Gets tables on this page
  1123.         $tab_sql  = 'SELECT table_name FROM ' . PMA_backquote($cfgRelation['table_coords'])
  1124.                   .   ' WHERE db_name = \'' . PMA_sqlAddslashes($db) . '\''
  1125.                   .   ' AND pdf_page_number = ' . $which_rel;
  1126.         $tab_rs   = PMA_query_as_cu($tab_sql, NULL, PMA_DBI_QUERY_STORE);
  1127.         if (!$tab_rs || !PMA_DBI_num_rows($tab_rs) > 0) {
  1128.             $pdf->PMA_PDF_die($GLOBALS['strPdfNoTables']);
  1129. //            die('No tables');
  1130.         }
  1131.         while ($curr_table = @PMA_DBI_fetch_assoc($tab_rs)) {
  1132.             $alltables[] = PMA_sqlAddslashes($curr_table['table_name']);
  1133.             //$intable     = '\'' . implode('\', \'', $alltables) . '\'';
  1134.         }
  1135.  
  1136.         //              make doc                    //
  1137.         if ($with_doc) {
  1138.             $pdf->SetAutoPageBreak('auto',15);
  1139.             $pdf->cMargin = 1;
  1140.             PMA_RT_DOC($alltables);
  1141.             $pdf->SetAutoPageBreak('auto');
  1142.             $pdf->cMargin = 0;
  1143.         }
  1144.  
  1145.         $pdf->Addpage();
  1146.  
  1147.  
  1148.         if ($with_doc) {
  1149.             $pdf->SetLink($pdf->PMA_links['RT']['-'],-1);
  1150.             $pdf->Bookmark($GLOBALS['strRelationalSchema']);
  1151.             $pdf->SetAlias('{00}', $pdf->PageNo()) ;
  1152.             $this->t_marg = 18;
  1153.             $this->b_marg = 18;
  1154.         }
  1155.  
  1156.                                 /* snip */
  1157.  
  1158.         foreach ($alltables AS $table) {
  1159.             if (!isset($this->tables[$table])) {
  1160.                 $this->tables[$table] = new PMA_RT_Table($table, $this->ff, $this->tablewidth);
  1161.             }
  1162.  
  1163.             if ($this->same_wide){
  1164.                 $this->tables[$table]->width = $this->tablewidth;
  1165.             }
  1166.             $this->PMA_RT_setMinMax($this->tables[$table]);
  1167.         }
  1168.         // Defines the scale factor
  1169.         $this->scale = ceil(max(($this->x_max - $this->x_min) / ($pdf->fh - $this->r_marg - $this->l_marg), ($this->y_max - $this->y_min) / ($pdf->fw - $this->t_marg - $this->b_marg)) * 100) / 100;
  1170.         $pdf->PMA_PDF_setScale($this->scale, $this->x_min, $this->y_min, $this->l_marg, $this->t_marg);
  1171.  
  1172.  
  1173.         // Builds and save the PDF document
  1174.         $pdf->PMA_PDF_setLineWidthScale(0.1);
  1175.  
  1176.         if ($show_grid) {
  1177.             $pdf->SetFontSize(10);
  1178.             $this->PMA_RT_strokeGrid();
  1179.         }
  1180.         $pdf->PMA_PDF_setFontSizeScale(14);
  1181.  
  1182.  
  1183. //        $sql    = 'SELECT * FROM ' . PMA_backquote($cfgRelation['relation'])
  1184. //                .   ' WHERE master_db   = \'' . PMA_sqlAddslashes($db) . '\' '
  1185. //                .   ' AND foreign_db    = \'' . PMA_sqlAddslashes($db) . '\' '
  1186. //                .   ' AND master_table  IN (' . $intable . ')'
  1187. //                .   ' AND foreign_table IN (' . $intable . ')';
  1188. //        $result =  PMA_query_as_cu($sql);
  1189. //
  1190. // lem9:
  1191. // previous logic was checking master tables and foreign tables
  1192. // but I think that looping on every table of the pdf page as a master
  1193. // and finding its foreigns is OK (then we can support innodb)
  1194.  
  1195.         $seen_a_relation = FALSE;
  1196.         foreach ($alltables AS $one_table) {
  1197.  
  1198.             $exist_rel = PMA_getForeigners($db, $one_table, '', 'both');
  1199.             if ($exist_rel) {
  1200.                 $seen_a_relation = TRUE;
  1201.                 foreach ($exist_rel AS $master_field => $rel) {
  1202.                     // put the foreign table on the schema only if selected
  1203.                     // by the user
  1204.                     // (do not use array_search() because we would have to
  1205.                     // to do a === FALSE and this is not PHP3 compatible)
  1206.  
  1207.                     if (PMA_isInto($rel['foreign_table'], $alltables)> -1) {
  1208.                         $this->PMA_RT_addRelation($one_table , $master_field, $rel['foreign_table'], $rel['foreign_field']);
  1209.                     }
  1210.  
  1211.                 } // end while
  1212.             } // end if
  1213.         } // end while
  1214.  
  1215.         // loic1: also show tables without relations
  1216. //        $norelations     = TRUE;
  1217. //        if ($result && PMA_DBI_num_rows($result) > 0) {
  1218. //            $norelations = FALSE;
  1219. //            while ($row = PMA_DBI_fetch_assoc($result)) {
  1220. //                $this->PMA_RT_addRelation($row['master_table'] , $row['master_field'], $row['foreign_table'], $row['foreign_field']);
  1221. //            }
  1222. //        }
  1223.  
  1224.  
  1225. //        if ($norelations == FALSE) {
  1226.         if ($seen_a_relation) {
  1227.             $this->PMA_RT_drawRelations($change_color);
  1228.         }
  1229.  
  1230.         $this->PMA_RT_drawTables($show_info,$change_color);
  1231.  
  1232.         $this->PMA_RT_showRt();
  1233.     } // end of the "PMA_RT()" method
  1234. } // end of the "PMA_RT" class
  1235.  
  1236. function PMA_RT_DOC($alltables ){
  1237.     global  $db, $pdf, $orientation, $paper;
  1238.     //TOC
  1239.     $pdf->addpage($GLOBALS['orientation']);
  1240.     $pdf->Cell(0,9, $GLOBALS['strTableOfContents'],1,0,'C');
  1241.     $pdf->Ln(15);
  1242.     $i = 1;
  1243.     foreach ($alltables AS $table) {
  1244.         $pdf->PMA_links['doc'][$table]['-'] = $pdf->AddLink();
  1245.         $pdf->SetX(10);
  1246.         //$pdf->Ln(1);
  1247.         $pdf->Cell(0,6,$GLOBALS['strPageNumber'] . ' {'.sprintf("%02d", $i).'}',0,0,'R',0,$pdf->PMA_links['doc'][$table]['-']);
  1248.         $pdf->SetX(10);
  1249.         $pdf->Cell(0,6,$i.' '. $table,0,1,'L',0,$pdf->PMA_links['doc'][$table]['-']);
  1250.  
  1251.         //$pdf->Ln(1);
  1252.         $result     = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';');
  1253.         while ($row = PMA_DBI_fetch_assoc($result)) {
  1254.             $pdf->SetX(20);
  1255.             $field_name = $row['Field'];
  1256.             $pdf->PMA_links['doc'][$table][$field_name] =$pdf->AddLink();
  1257.             //$pdf->Cell(0,6,$field_name,0,1,'L',0,$pdf->PMA_links['doc'][$table][$field_name]);
  1258.         }
  1259.         $lasttable = $table;
  1260.         $i++;
  1261.     }
  1262.     $pdf->PMA_links['RT']['-'] =$pdf->AddLink();
  1263.     $pdf->SetX(10);
  1264.     $pdf->Cell(0,6,$GLOBALS['strPageNumber'] . ' {00}',0,0,'R',0,$pdf->PMA_links['doc'][$lasttable]['-']);
  1265.     $pdf->SetX(10);
  1266.     $pdf->Cell(0,6,$i.' '. $GLOBALS['strRelationalSchema'],0,1,'L',0,$pdf->PMA_links['RT']['-']);
  1267.     $z = 0;
  1268.     foreach ($alltables AS $table) {
  1269.         $z++;
  1270.         $pdf->addpage($GLOBALS['orientation']);
  1271.         $pdf->Bookmark($table);
  1272.         $pdf->SetAlias('{'.sprintf("%02d", $z).'}', $pdf->PageNo()) ;
  1273.         $pdf->PMA_links['RT'][$table]['-'] =$pdf->AddLink();
  1274.         $pdf->SetLink($pdf->PMA_links['doc'][$table]['-'],-1);
  1275.         $pdf->SetFont('', 'B',18);
  1276.         $pdf->Cell(0,8, $z .' '.$table,1,1,'C',0,$pdf->PMA_links['RT'][$table]['-']);
  1277.         $pdf->SetFont('', '',8);
  1278.         $pdf->ln();
  1279.  
  1280.         $cfgRelation  = PMA_getRelationsParam();
  1281.         if ($cfgRelation['commwork'] || PMA_MYSQL_INT_VERSION >= 40100) {
  1282.             $comments = PMA_getComments($db, $table);
  1283.         }
  1284.         if ($cfgRelation['mimework']) {
  1285.             $mime_map = PMA_getMIME($db, $table, true);
  1286.         }
  1287.  
  1288.  
  1289.         /**
  1290.          * Gets table informations
  1291.          */
  1292.         $result       = PMA_DBI_query('SHOW TABLE STATUS LIKE \'' . PMA_sqlAddslashes($table, TRUE) . '\';', NULL, PMA_DBI_QUERY_STORE);
  1293.         $showtable    = PMA_DBI_fetch_assoc($result);
  1294.         $num_rows     = (isset($showtable['Rows']) ? $showtable['Rows'] : 0);
  1295.         $show_comment = (isset($showtable['Comment']) ? $showtable['Comment'] : '');
  1296.         $create_time  = (isset($showtable['Create_time']) ? PMA_localisedDate(strtotime($showtable['Create_time'])) : '');
  1297.         $update_time  = (isset($showtable['Update_time']) ? PMA_localisedDate(strtotime($showtable['Update_time'])) : '');
  1298.         $check_time   = (isset($showtable['Check_time']) ? PMA_localisedDate(strtotime($showtable['Check_time'])) : '');
  1299.  
  1300.         PMA_DBI_free_result($result);
  1301.         unset($result);
  1302.  
  1303.  
  1304.         /**
  1305.          * Gets table keys and retains them
  1306.          */
  1307.         $result       = PMA_DBI_query('SHOW KEYS FROM ' . PMA_backquote($table) . ';');
  1308.         $primary      = '';
  1309.         $indexes      = array();
  1310.         $lastIndex    = '';
  1311.         $indexes_info = array();
  1312.         $indexes_data = array();
  1313.         $pk_array     = array(); // will be use to emphasis prim. keys in the table
  1314.                                  // view
  1315.         while ($row = PMA_DBI_fetch_assoc($result)) {
  1316.             // Backups the list of primary keys
  1317.             if ($row['Key_name'] == 'PRIMARY') {
  1318.                 $primary   .= $row['Column_name'] . ', ';
  1319.                 $pk_array[$row['Column_name']] = 1;
  1320.             }
  1321.             // Retains keys informations
  1322.             if ($row['Key_name'] != $lastIndex ){
  1323.                 $indexes[] = $row['Key_name'];
  1324.                 $lastIndex = $row['Key_name'];
  1325.             }
  1326.             $indexes_info[$row['Key_name']]['Sequences'][]     = $row['Seq_in_index'];
  1327.             $indexes_info[$row['Key_name']]['Non_unique']      = $row['Non_unique'];
  1328.             if (isset($row['Cardinality'])) {
  1329.                 $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
  1330.             }
  1331.             // I don't know what does following column mean....
  1332.             // $indexes_info[$row['Key_name']]['Packed']          = $row['Packed'];
  1333.             $indexes_info[$row['Key_name']]['Comment']         = $row['Comment'];
  1334.  
  1335.             $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name']  = $row['Column_name'];
  1336.             if (isset($row['Sub_part'])) {
  1337.                 $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
  1338.             }
  1339.  
  1340.         } // end while
  1341.         if ($result) {
  1342.             PMA_DBI_free_result($result);
  1343.         }
  1344.  
  1345.  
  1346.         /**
  1347.          * Gets fields properties
  1348.          */
  1349.         $result      = PMA_DBI_query('SHOW FIELDS FROM ' . PMA_backquote($table) . ';', NULL, PMA_DBI_QUERY_STORE);
  1350.         $fields_cnt  = PMA_DBI_num_rows($result);
  1351.  
  1352.  
  1353.         // Check if we can use Relations (Mike Beck)
  1354.         if (!empty($cfgRelation['relation'])) {
  1355.             // Find which tables are related with the current one and write it in
  1356.             // an array
  1357.             $res_rel = PMA_getForeigners($db, $table);
  1358.  
  1359.             if (count($res_rel) > 0) {
  1360.                 $have_rel = TRUE;
  1361.             } else {
  1362.                 $have_rel = FALSE;
  1363.             }
  1364.         }
  1365.         else {
  1366.             $have_rel = FALSE;
  1367.         } // end if
  1368.  
  1369.  
  1370.         /**
  1371.          * Displays the comments of the table if MySQL >= 3.23
  1372.          */
  1373.  
  1374.         $break = false;
  1375.         if (!empty($show_comment)) {
  1376.             $pdf->Cell(0,3,$GLOBALS['strTableComments'] . ' : ' . $show_comment,0,1);
  1377.             $break = true;
  1378.         }
  1379.  
  1380.         if (!empty($create_time)) {
  1381.             $pdf->Cell(0,3,$GLOBALS['strStatCreateTime'] . ': ' . $create_time,0,1);
  1382.             $break = true;
  1383.         }
  1384.  
  1385.         if (!empty($update_time)) {
  1386.             $pdf->Cell(0,3,$GLOBALS['strStatUpdateTime'] . ': ' . $update_time,0,1);
  1387.             $break = true;
  1388.         }
  1389.  
  1390.         if (!empty($check_time)) {
  1391.             $pdf->Cell(0,3,$GLOBALS['strStatCheckTime'] . ': ' . $check_time,0,1);
  1392.             $break = true;
  1393.         }
  1394.  
  1395.         if ($break == true) {
  1396.             $pdf->Cell(0,3,'',0,1);
  1397.             $pdf->Ln();
  1398.         }
  1399.  
  1400.         $i = 0;
  1401.         $pdf->SetFont('', 'B');
  1402.         if (isset($orientation) && $orientation == 'L') {
  1403.             $pdf->Cell(25,8,ucfirst($GLOBALS['strField']),1,0,'C');
  1404.             $pdf->Cell(20,8,ucfirst($GLOBALS['strType']),1,0,'C');
  1405.             $pdf->Cell(20,8,ucfirst($GLOBALS['strAttr']),1,0,'C');
  1406.             $pdf->Cell(10,8,ucfirst($GLOBALS['strNull']),1,0,'C');
  1407.             $pdf->Cell(20,8,ucfirst($GLOBALS['strDefault']),1,0,'C');
  1408.             $pdf->Cell(25,8,ucfirst($GLOBALS['strExtra']),1,0,'C');
  1409.             $pdf->Cell(45,8,ucfirst($GLOBALS['strLinksTo']),1,0,'C');
  1410.  
  1411.             if ($paper == 'A4') {
  1412.                 $comments_width = 67;
  1413.             } else {
  1414.                 // this is really intended for 'letter'
  1415.                 // TODO: find optimal width for all formats
  1416.                 $comments_width = 50;
  1417.             }
  1418.             $pdf->Cell($comments_width,8,ucfirst($GLOBALS['strComments']),1,0,'C');
  1419.             $pdf->Cell(45,8,'MIME',1,1,'C');
  1420.             $pdf->SetWidths(array(25,20,20,10,20,25,45,$comments_width,45));
  1421.         } else {
  1422.             $pdf->Cell(20,8,ucfirst($GLOBALS['strField']),1,0,'C');
  1423.             $pdf->Cell(20,8,ucfirst($GLOBALS['strType']),1,0,'C');
  1424.             $pdf->Cell(20,8,ucfirst($GLOBALS['strAttr']),1,0,'C');
  1425.             $pdf->Cell(10,8,ucfirst($GLOBALS['strNull']),1,0,'C');
  1426.             $pdf->Cell(15,8,ucfirst($GLOBALS['strDefault']),1,0,'C');
  1427.             $pdf->Cell(15,8,ucfirst($GLOBALS['strExtra']),1,0,'C');
  1428.             $pdf->Cell(30,8,ucfirst($GLOBALS['strLinksTo']),1,0,'C');
  1429.             $pdf->Cell(30,8,ucfirst($GLOBALS['strComments']),1,0,'C');
  1430.             $pdf->Cell(30,8,'MIME',1,1,'C');
  1431.             $pdf->SetWidths(array(20,20,20,10,15,15,30,30,30));
  1432.         }
  1433.         $pdf->SetFont('', '');
  1434.  
  1435.         while ($row = PMA_DBI_fetch_assoc($result)) {
  1436.             $bgcolor = ($i % 2) ?$GLOBALS['cfg']['BgcolorOne'] : $GLOBALS['cfg']['BgcolorTwo'];
  1437.             $i++;
  1438.  
  1439.             $type             = $row['Type'];
  1440.             // reformat mysql query output - staybyte - 9. June 2001
  1441.             // loic1: set or enum types: slashes single quotes inside options
  1442.             if (preg_match('@^(set|enum)\((.+)\)$@i', $type, $tmp)) {
  1443.                 $tmp[2]       = substr(preg_replace("@([^,])''@", "\\1\\'", ',' . $tmp[2]), 1);
  1444.                 $type         = $tmp[1] . '(' . str_replace(',', ', ', $tmp[2]) . ')';
  1445.                 $type_nowrap  = '';
  1446.  
  1447.                 $binary       = 0;
  1448.                 $unsigned     = 0;
  1449.                 $zerofill     = 0;
  1450.             } else {
  1451.                 $type_nowrap  = ' nowrap="nowrap"';
  1452.                 $type         = preg_replace('@BINARY@i', '', $type);
  1453.                 $type         = preg_replace('@ZEROFILL@i', '', $type);
  1454.                 $type         = preg_replace('@UNSIGNED@i', '', $type);
  1455.                 if (empty($type)) {
  1456.                     $type     = ' ';
  1457.                 }
  1458.  
  1459.                 $binary       = stristr($row['Type'], 'BINARY');
  1460.                 $unsigned     = stristr($row['Type'], 'UNSIGNED');
  1461.                 $zerofill     = stristr($row['Type'], 'ZEROFILL');
  1462.             }
  1463.             $strAttribute     = ' ';
  1464.             if ($binary) {
  1465.                 $strAttribute = 'BINARY';
  1466.             }
  1467.             if ($unsigned) {
  1468.                 $strAttribute = 'UNSIGNED';
  1469.             }
  1470.             if ($zerofill) {
  1471.                 $strAttribute = 'UNSIGNED ZEROFILL';
  1472.             }
  1473.             if (!isset($row['Default'])) {
  1474.                 if ($row['Null'] != '') {
  1475.                     $row['Default'] = 'NULL';
  1476.                 }
  1477.             }
  1478.             $field_name = $row['Field'];
  1479.             //$pdf->Ln();
  1480.             $pdf->PMA_links['RT'][$table][$field_name] =$pdf->AddLink();
  1481.             $pdf->Bookmark($field_name,1,-1);
  1482.             $pdf->SetLink($pdf->PMA_links['doc'][$table][$field_name],-1);
  1483.             $pdf_row = array($field_name ,
  1484.                             $type ,
  1485.                             $strAttribute ,
  1486.                             ($row['Null'] == '') ? $GLOBALS['strNo'] : $GLOBALS['strYes'],
  1487.                             ((isset($row['Default'])) ?  $row['Default'] : ''),
  1488.                             $row['Extra']  ,
  1489.                             ((isset($res_rel[$field_name])) ? $res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field'] : ''),
  1490.                             ((isset($comments[$field_name])) ? $comments[$field_name]  : '' ),
  1491.                             ((isset($mime_map) && isset($mime_map[$field_name])) ? str_replace('_', '/', $mime_map[$field_name]['mimetype'])  : '' )
  1492.                             );
  1493.             $links[0] = $pdf->PMA_links['RT'][$table][$field_name];
  1494.             if (isset($res_rel[$field_name]['foreign_table']) AND
  1495.                 isset($res_rel[$field_name]['foreign_field']) AND
  1496.                 isset($pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']])
  1497.               ) $links[6] = $pdf->PMA_links['doc'][$res_rel[$field_name]['foreign_table']][$res_rel[$field_name]['foreign_field']];
  1498.               else unset($links[6]);
  1499.             $pdf->Row($pdf_row, $links);
  1500.  
  1501.              /*$pdf->Cell(20,8,$field_name,1,0,'L',0,$pdf->PMA_links['RT'][$table][$field_name]);
  1502.                 //echo '    ' . $field_name . ' ' . "\n";
  1503.             }
  1504.         $pdf->Cell(20,8,$type,1,0,'L');
  1505.         $pdf->Cell(20,8,$strAttribute,1,0,'L');
  1506.         $pdf->Cell(15,8,,1,0,'L');
  1507.         $pdf->Cell(15,8,((isset($row['Default'])) ?  $row['Default'] : ''),1,0,'L');
  1508.         $pdf->Cell(15,8,$row['Extra'],1,0,'L');
  1509.            if ($have_rel) {
  1510.                 if (isset($res_rel[$field_name])) {
  1511.                     $pdf->Cell(30,8,$res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field'],1,0,'L');
  1512.                 }
  1513.             }
  1514.             if ($cfgRelation['commwork']) {
  1515.                 if (isset($comments[$field_name])) {
  1516.                     $pdf->Cell(0,8,$comments[$field_name],1,0,'L');
  1517.                 }
  1518.             } */
  1519.         } // end while
  1520.         $pdf->SetFont('', '',14);
  1521.         PMA_DBI_free_result($result);
  1522.     }//end each
  1523.  
  1524.  
  1525. } // end function PMA_RT_DOC
  1526.  
  1527.  
  1528. /**
  1529.  * Main logic
  1530.  */
  1531. if (!isset($pdf_page_number)) {
  1532.     $pdf_page_number  = 1;
  1533. }
  1534. $show_grid            = (isset($show_grid) && $show_grid == 'on') ? 1 : 0;
  1535. $show_color           = (isset($show_color) && $show_color == 'on') ? 1 : 0;
  1536. $show_table_dimension = (isset($show_table_dimension) && $show_table_dimension == 'on') ? 1 : 0;
  1537. $all_tab_same_wide    = (isset($all_tab_same_wide) && $all_tab_same_wide == 'on') ? 1 : 0;
  1538. $with_doc             = (isset($with_doc) && $with_doc == 'on') ? 1 : 0;
  1539. $orientation          = (isset($orientation) && $orientation == 'P') ? 'P' : 'L';
  1540. $paper                = isset($paper) ? $paper : 'A4';
  1541. PMA_DBI_select_db($db);
  1542.  
  1543. $rt = new PMA_RT($pdf_page_number, $show_table_dimension, $show_color, $show_grid, $all_tab_same_wide, $orientation, $paper);
  1544. ?>
  1545.